package com.LachesismStorm.lachesism.member.service.impl;

import com.LachesismStorm.lachesism.ai.kimi.Message;
import com.LachesismStorm.lachesism.core.service.RedisService;
import com.LachesismStorm.lachesism.core.util.CommonUtil;
import com.LachesismStorm.lachesism.core.util.LachesismTools;
import com.LachesismStorm.lachesism.member.mapper.OfficalAccountMapper;
import com.LachesismStorm.lachesism.member.service.OfficalAccountService;
import com.LachesismStorm.lachesism.member.service.ofaServiceUtil.recordDiet;
import com.LachesismStorm.lachesism.member.vo.UmsMember;
import com.LachesismStorm.lachesism.member.vo.ofaVO.LocationInfo;
import com.LachesismStorm.lachesism.member.vo.ofaVO.MessageTextInfo;
import com.LachesismStorm.lachesism.member.vo.ofaVO.OfaMsgLog;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.github.wxpay.sdk.WXPayUtil;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;

import static com.LachesismStorm.lachesism.ai.kimi.MoonshotAiUtils.chat;


/**
 * @Author lachesism
 * @Date 2024-08-02 01:09
 **/
@Service
public class OfficalAccountServiceImpl implements OfficalAccountService {
    @Resource
    private RedisService redisService;
    @Resource
    private recordDiet dietService;
    @Resource
    private OfficalAccountMapper officalAccountMapper;

//    @Override
//    public String replyText(Map<String, String> map) throws Exception {
//        String jsonString = JSONObject.toJSONString(map);
//        MessageTextInfo messageTextInfo = JSONObject.parseObject(jsonString, MessageTextInfo.class);
//        System.out.println("【消息】接收到来自微信服务器的消息：" + jsonString);
//        String openId = messageTextInfo.getFromUserName();
//        if (redisService.getWithTimeout(openId) == null) {
//            return normalMessage(messageTextInfo, map);
//        } else {
//            return kimiChat(messageTextInfo, map);
//        }
//    }

    @Override
    public String replyText1(Map<String, String> map) throws Exception {
        String jsonString = JSONObject.toJSONString(map);
        MessageTextInfo messageTextInfo = JSONObject.parseObject(jsonString, MessageTextInfo.class);
        System.out.println("【消息】接收到来自微信服务器的消息：" + jsonString);
        String openId = messageTextInfo.getFromUserName();
        if (redisService.getWithTimeout(openId) == null) {
            return firstChat(messageTextInfo, map);
        } else {
            String type = (String) redisService.get(openId);
            if (type.equals("新用户饮食")) {
                return dietService.recordDiet(messageTextInfo);
            }
            return continueChat(messageTextInfo, map);
        }

    }

    private String continueChat(MessageTextInfo messageTextInfo, Map<String, String> map) throws Exception {
        String content = map.get("Content");
        if (content.equals("关闭")) {
            return closeChat(messageTextInfo);
        } else {
            String openId = messageTextInfo.getFromUserName();
            String chatType = (String) redisService.getWithTimeout(openId);
            switch (chatType) {
                case "饮食":
                    return dietService.continueRecordDiet(messageTextInfo);
                case "对话":
                    return continueAIChat(messageTextInfo);
                case "阵容":
                    return continueSearchTft(messageTextInfo);
                case "金价":
                    return continueGetGoldPrice(messageTextInfo);
                case "钓鱼":
                    return continueFishing(messageTextInfo);
                default:
                    return "success";
            }
        }

    }

    private String continueFishing(MessageTextInfo messageTextInfo) throws Exception {
        String openId = messageTextInfo.getFromUserName();
        Integer withTimeout = (Integer) redisService.getWithTimeout(openId + "fish");
        String content;
        if (withTimeout == null) {
            content = "好的，开始钓鱼";
        } else {
            content = "已钓鱼" + withTimeout + "分钟";
        }
        SortedMap<String, String> req = new TreeMap<String, String>();
        req.put("FromUserName", messageTextInfo.getToUserName());
        req.put("ToUserName", openId);
        req.put("CreateTime", String.valueOf(messageTextInfo.getCreateTime().getTime()));
        req.put("MsgType", "text");
        req.put("Content", "好的，开始钓鱼");
        return LachesismTools.convertMapToXml(req);
    }

    private String continueGetGoldPrice(MessageTextInfo messageTextInfo) {
        return null;
    }

    private String continueSearchTft(MessageTextInfo messageTextInfo) throws Exception {
        String openId = messageTextInfo.getFromUserName();
        SortedMap<String, String> req = new TreeMap<String, String>();
        req.put("FromUserName", messageTextInfo.getToUserName());
        req.put("ToUserName", openId);
        req.put("CreateTime", String.valueOf(messageTextInfo.getCreateTime().getTime()));
        req.put("MsgType", "text");
        req.put("Content", "还没写完");
        return LachesismTools.convertMapToXml(req);
    }

    private String continueAIChat(MessageTextInfo messageTextInfo) throws Exception {
        String openId = messageTextInfo.getFromUserName();
        SortedMap<String, String> req = new TreeMap<String, String>();
        req.put("FromUserName", messageTextInfo.getToUserName());
        req.put("ToUserName", openId);
        req.put("CreateTime", String.valueOf(messageTextInfo.getCreateTime().getTime()));
        req.put("MsgType", "text");
        req.put("Content", "还没写完");
        return LachesismTools.convertMapToXml(req);
    }





    private String addNewUser(MessageTextInfo messageTextInfo, Map<String, String> map) {
        return null;
    }

    private String firstChat(MessageTextInfo messageTextInfo, Map<String, String> map) throws Exception {
        String chatType = map.get("Content");
        switch (chatType) {
            case "饮食":
                return dietService.recordDiet(messageTextInfo);
            case "对话":
                return beginChat(messageTextInfo);
            case "阵容":
                return searchTft(messageTextInfo);
            case "金价":
                return getGoldPrice(messageTextInfo);
            case "钓鱼":
                return fishing(messageTextInfo);
            default:
                return introduce(messageTextInfo);
        }
    }
    public Boolean checkIsNewUser(String openId) {
        UmsMember member = officalAccountMapper.getUserInfoByOpenId(openId);
        return LachesismTools.isNotEmpty(member);
    }

    private String introduce(MessageTextInfo messageTextInfo) throws Exception {
        String openId = messageTextInfo.getFromUserName();
        redisService.set(messageTextInfo.getFromUserName(), "金价");
        SortedMap<String, String> req = new TreeMap<String, String>();
        req.put("FromUserName", messageTextInfo.getToUserName());
        req.put("ToUserName", openId);
        req.put("CreateTime", String.valueOf(messageTextInfo.getCreateTime().getTime()));
        req.put("MsgType", "text");
        req.put("Content", "监测到你不知道怎么用" +
                "\n1.记录吃饭 回复【饮食】" +
                "\n2.开始AI对话 回复【对话】" +
                "\n3.查询云顶阵容 回复【阵容】" +
                "\n4.查询实时金价 回复【金价】" +
                "\n5.钓鱼 回复【钓鱼】" +
                "\n在任何状态下都可以回复【关闭】来结束当前情景，然后开启下一次你需要的任务");
        return LachesismTools.convertMapToXml(req);
    }

    private String fishing(MessageTextInfo messageTextInfo) throws Exception {
        String openId = messageTextInfo.getFromUserName();
        redisService.set(messageTextInfo.getFromUserName(), "钓鱼");
        SortedMap<String, String> req = new TreeMap<String, String>();
        req.put("FromUserName", messageTextInfo.getToUserName());
        req.put("ToUserName", openId);
        req.put("CreateTime", String.valueOf(messageTextInfo.getCreateTime().getTime()));
        req.put("MsgType", "text");
        req.put("Content", "好的，切换到钓鱼模式，回复钓鱼开始钓鱼");
        return LachesismTools.convertMapToXml(req);
    }

    private String getGoldPrice(MessageTextInfo messageTextInfo) throws Exception {
        String openId = messageTextInfo.getFromUserName();
        redisService.set(messageTextInfo.getFromUserName(), "金价");
        SortedMap<String, String> req = new TreeMap<String, String>();
        req.put("FromUserName", messageTextInfo.getToUserName());
        req.put("ToUserName", openId);
        req.put("CreateTime", String.valueOf(messageTextInfo.getCreateTime().getTime()));
        req.put("MsgType", "text");
        req.put("Content", "好的，切换到金价查询，后续输入任何内容都不理会直接返回当前金价");
        return LachesismTools.convertMapToXml(req);
    }

    private String searchTft(MessageTextInfo messageTextInfo) throws Exception {
        String openId = messageTextInfo.getFromUserName();
        redisService.set(messageTextInfo.getFromUserName(), "阵容");
        SortedMap<String, String> req = new TreeMap<String, String>();
        req.put("FromUserName", messageTextInfo.getToUserName());
        req.put("ToUserName", openId);
        req.put("CreateTime", String.valueOf(messageTextInfo.getCreateTime().getTime()));
        req.put("MsgType", "text");
        req.put("Content", "好的，切换到查找阵容，后续关键词查找云顶阵容");
        return LachesismTools.convertMapToXml(req);
    }

    private String beginChat(MessageTextInfo messageTextInfo) throws Exception {
        String openId = messageTextInfo.getFromUserName();
        redisService.set(messageTextInfo.getFromUserName(), "对话");
        SortedMap<String, String> req = new TreeMap<String, String>();
        req.put("FromUserName", messageTextInfo.getToUserName());
        req.put("ToUserName", openId);
        req.put("CreateTime", String.valueOf(messageTextInfo.getCreateTime().getTime()));
        req.put("MsgType", "text");
        req.put("Content", "好的，切换到ai对话，后续输入任何内容直接开始对话");
        return LachesismTools.convertMapToXml(req);
    }


    private String closeChat(MessageTextInfo messageTextInfo) throws Exception {
        String openId = messageTextInfo.getFromUserName();
        redisService.del(messageTextInfo.getFromUserName());
        SortedMap<String, String> req = new TreeMap<String, String>();
        req.put("FromUserName", messageTextInfo.getToUserName());
        req.put("ToUserName", openId);
        req.put("CreateTime", String.valueOf(messageTextInfo.getCreateTime().getTime()));
        req.put("MsgType", "text");
        req.put("Content", "已关闭当前任务" +
                "\n1.记录吃饭 回复【饮食】" +
                "\n2.开始AI对话 回复【对话】" +
                "\n3.查询阵容 回复【阵容】" +
                "\n4.查询实时金价 回复【金价】" +
                "\n5.钓鱼 回复【钓鱼】");
        return LachesismTools.convertMapToXml(req);
    }

    @Override
    public void addMsgLog(Map<String, String> map) {
        String msgType = map.get("MsgType");
        OfaMsgLog ofaMsgLog = new OfaMsgLog();
        switch (msgType) {
            case "text":
                ofaMsgLog.setMsgType(1);
                ofaMsgLog.setContent(map.get("Content"));
                addMsgLog(ofaMsgLog, map);
                break;
            case "image":
                ofaMsgLog.setMsgType(2);
                ofaMsgLog.setPicUrl(map.get("PicUrl"));
                addMsgLog(ofaMsgLog, map);
                break;
            case "location":
                ofaMsgLog.setMsgType(3);
                ofaMsgLog.setLatitude(map.get("Location_Y"));
                ofaMsgLog.setLongitude(map.get("Location_X"));
                ofaMsgLog.setContent("位置信息");
                addMsgLog(ofaMsgLog, map);
            default:
        }
    }

    @Override
    public String replyLocation(Map<String, String> map) throws Exception {
        String jsonString = JSONObject.toJSONString(map);
        LocationInfo locationInfo = JSONObject.parseObject(jsonString, LocationInfo.class);
        System.out.println("【位置】接收到来自微信服务器的位置：\n" + locationInfo);
        return returnLocation(locationInfo);
    }


    public void addMsgLog(OfaMsgLog ofaMsgLog, Map<String, String> map) {
        Date createTime = LachesismTools.stringToDate(map.get("CreateTime"));
        ofaMsgLog.setCreateTime(createTime);
        ofaMsgLog.setOpenId(map.get("FromUserName"));
        ofaMsgLog.setMsgId(map.get("MsgId"));
        ofaMsgLog.setIsRead(0);
        if (ofaMsgLog.getContent().equals("位置信息")) {
            officalAccountMapper.addMsgLocation(ofaMsgLog);
        } else {
            officalAccountMapper.addMsgLog(ofaMsgLog);

        }
    }

    public String returnLocation(LocationInfo locationInfo) throws Exception {
        String openId = locationInfo.getFromUserName();
        SortedMap<String, String> req = new TreeMap<String, String>();
        req.put("FromUserName", locationInfo.getToUserName());
        req.put("ToUserName", openId);
        req.put("CreateTime", String.valueOf(locationInfo.getCreateTime().getTime()));
        req.put("MsgType", "text");
        req.put("Content", "纬度为" + locationInfo.getLocation_X() + "经度为" + locationInfo.getLocation_Y());
        return WXPayUtil.mapToXml(req);

    }

    public String normalMessage(MessageTextInfo messageTextInfo, Map<String, String> map) throws Exception {
        if (map.get("Content").equals("开始对话")) {
            String openId = messageTextInfo.getFromUserName();
            String sessionId = LachesismTools.generateRandomCode(10);
            redisService.set(openId, sessionId, 3);
            SortedMap<String, String> req = new TreeMap<String, String>();
            req.put("FromUserName", messageTextInfo.getToUserName());
            req.put("ToUserName", openId);
            req.put("CreateTime", String.valueOf(messageTextInfo.getCreateTime().getTime()));
            req.put("MsgType", "text");
            req.put("Content", beginChatWithKimi(map.get("Content")));
            officalAccountMapper.saveContent(openId, sessionId, map.get("Content"));
            return LachesismTools.convertMapToXml(req);
        } else {
            return "success";
        }
    }

    public String kimiChat(MessageTextInfo messageTextInfo, Map<String, String> map) throws Exception {

        String openId = messageTextInfo.getFromUserName();
        String sessionId = (String) redisService.getWithTimeout(openId);
        List<Message> messages = officalAccountMapper.getHistoryBySessionId(sessionId);
        officalAccountMapper.saveContent(openId, sessionId, map.get("Content"));
        if (messages.isEmpty()) {
            String content = beginChatWithKimi(map.get("Content"));
            SortedMap<String, String> req = new TreeMap<String, String>();
            req.put("FromUserName", messageTextInfo.getToUserName());
            req.put("ToUserName", openId);
            req.put("CreateTime", String.valueOf(messageTextInfo.getCreateTime().getTime()));
            req.put("MsgType", "text");
            req.put("Content", content);
            return WXPayUtil.mapToXml(req);
        } else {
            String content = chatWithKimi(messages, map.get("Content"));
            SortedMap<String, String> req = new TreeMap<String, String>();
            req.put("FromUserName", messageTextInfo.getToUserName());
            req.put("ToUserName", openId);
            req.put("CreateTime", String.valueOf(messageTextInfo.getCreateTime().getTime()));
            req.put("MsgType", "text");
            req.put("Content", content);
            return WXPayUtil.mapToXml(req);
        }
    }

    public String beginChatWithKimi(String content) {
        List<Message> messages = new ArrayList<>();
        Message message = new Message();
        Message newmessage = new Message();
        message.setRole("system");
        message.setContent("你是 Kimi，由 Moonshot AI 提供的人工智能助手，你更擅长中文和英文的对话。你会为用户提供安全，有帮助，准确的回答。同时，你会拒绝一切涉及恐怖主义，种族歧视，黄色暴力等问题的回答。Moonshot AI 为专有名词，不可翻译成其他语言。");
        newmessage.setRole("user");
        newmessage.setContent(content);
        messages.add(message);
        messages.add(newmessage);
        return chat("moonshot-v1-8k", messages).get(0);
    }

    public String chatWithKimi(List<Message> messages, String content) {
        Message newmessage = new Message();
        newmessage.setRole("user");
        newmessage.setContent(content);
        messages.add(newmessage);
        return chat("moonshot-v1-8k", messages).get(0);
    }

    public String getToken() {
        String token = (String) redisService.getWithTimeout("token");
        if (token == null || token.equals("")) {
            String accessToken = getStableAccessToken();
            setAccessToken(accessToken);
            return accessToken;
        }
        return token;
    }


    private String getStableAccessToken() {
        String urlString = "https://api.weixin.qq.com/cgi-bin/stable_token";
        JSONObject json = new JSONObject();
        json.put("grant_type", "client_credential");
        json.put("appid", "wx8e6187baf97db085");
        json.put("secret", "01e5ff1f86f00adffffa9a2078f53eed");
        String result = CommonUtil.httpsRequest(urlString, "POST", json.toString());

        Map<String, String> parse = JSON.parseObject(result, new TypeReference<Map<String, String>>() {
        });
        System.out.println(parse);
        String token = parse.get("access_token");
        return token;
    }

    private void setAccessToken(String token) {
        redisService.set("token", token, 2);
    }
}
